# uncompyle6 version 3.2.3
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.8 |Anaconda custom (64-bit)| (default, Feb 21 2019, 18:30:04) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: site-packages\gevent\threading.py
"""
Implementation of the standard :mod:`threading` using greenlets.

.. note::

    This module is a helper for :mod:`gevent.monkey` and is not
    intended to be used directly. For spawning greenlets in your
    applications, prefer higher level constructs like
    :class:`gevent.Greenlet` class or :func:`gevent.spawn`.
"""
from __future__ import absolute_import

__implements__ = [
    "local",
    "_start_new_thread",
    "_allocate_lock",
    "Lock",
    "_get_ident",
    "_sleep",
    "_DummyThread",
]
import threading as __threading__

_DummyThread_ = __threading__._DummyThread
from gevent.local import local
from gevent.thread import (
    start_new_thread as _start_new_thread,
    allocate_lock as _allocate_lock,
    get_ident as _get_ident,
)
from gevent._compat import PYPY
from gevent.hub import sleep as _sleep, getcurrent

local = local
start_new_thread = _start_new_thread
allocate_lock = _allocate_lock
_get_ident = _get_ident
_sleep = _sleep
getcurrent = getcurrent
Lock = _allocate_lock


def _cleanup(g):
    __threading__._active.pop(id(g), None)


def _make_cleanup_id(gid):
    def _(_r):
        __threading__._active.pop(gid, None)

    return _


_weakref = None


class _DummyThread(_DummyThread_):
    _Thread__stopped = _is_stopped = _stopped = False
    _Thread__initialized = _initialized = True
    _Thread__daemonic = _daemonic = True
    _Thread__args = _args = ()
    _Thread__kwargs = _kwargs = None
    _Thread__target = _target = None
    _Thread_ident = _ident = None
    _Thread__started = _started = __threading__.Event()
    _Thread__started.set()
    _tstate_lock = None

    def __init__(self):
        global _weakref
        self._name = self._Thread__name = __threading__._newname("DummyThread-%d")
        self._set_ident()
        g = getcurrent()
        gid = _get_ident(g)
        __threading__._active[gid] = self
        rawlink = getattr(g, "rawlink", None)
        if rawlink is not None:
            rawlink(_cleanup)
        else:
            if _weakref is None:
                _weakref = __import__("weakref")
            ref = _weakref.ref(g, _make_cleanup_id(gid))
            self._DummyThread__raw_ref = ref

    def _Thread__stop(self):
        pass

    _stop = _Thread__stop

    def _wait_for_tstate_lock(self, *args, **kwargs):
        pass


if hasattr(__threading__, "main_thread"):

    def main_native_thread():
        return __threading__.main_thread()


else:
    _main_threads = [
        (_k, _v)
        for _k, _v in __threading__._active.items()
        if isinstance(_v, __threading__._MainThread)
    ]
    if not len(_main_threads) == 1:
        raise AssertionError("Too many main threads")

    def main_native_thread():
        return _main_threads[0][1]


if _get_ident() not in __threading__._active:
    _v = main_native_thread()
    _k = _v.ident
    del __threading__._active[_k]
    _v._ident = _v._Thread__ident = _get_ident()
    __threading__._active[_get_ident()] = _v
    del _k
    del _v
    if not PYPY:
        _MAIN_THREAD = (
            __threading__._get_ident()
            if hasattr(__threading__, "_get_ident")
            else __threading__.get_ident()
        )

        class _active(dict):
            def __delitem__(self, k):
                if k == _MAIN_THREAD:
                    if k not in self:
                        return
                    dict.__delitem__(self, k)

        __threading__._active = _active(__threading__._active)
import sys

if sys.version_info[:2] >= (3, 4):

    class Thread(__threading__.Thread):
        _greenlet = None

        def is_alive(self):
            return bool(self._greenlet)

        isAlive = is_alive

        def _set_tstate_lock(self):
            self._greenlet = getcurrent()

        def run(self):
            try:
                super(Thread, self).run()
            finally:
                self._greenlet = None
                self._stop()

        def join(self, timeout=None):
            if "_greenlet" not in self.__dict__:
                raise RuntimeError("Cannot join an inactive thread")
            if self._greenlet is None:
                return
            self._greenlet.join(timeout=timeout)

        def _wait_for_tstate_lock(self, *args, **kwargs):
            raise NotImplementedError()

    __implements__.append("Thread")
if sys.version_info[:2] >= (3, 3):
    __implements__.remove("_get_ident")
    __implements__.append("get_ident")
    get_ident = _get_ident
    __implements__.remove("_sleep")
    if not hasattr(__threading__, "_CRLock"):
        raise AssertionError("Unsupported Python version")
    _CRLock = None
    __implements__.append("_CRLock")
